{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "from bqplot import LinearScale, Bins, Axis, Figure"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Bins Mark\n",
    "\n",
    "This `Mark` is essentially the same as the `Hist` `Mark` from a user point of view, but is actually a `Bars` instance that bins sample data.\n",
    "\n",
    "The difference with `Hist` is that the binning is done in the backend, so it will work better for large data as it does not have to ship the whole data back and forth to the frontend."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create a sample of Gaussian draws\n",
    "np.random.seed(0)\n",
    "x_data = np.random.randn(1000)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Give the `Hist` mark the data you want to perform as the `sample` argument, and also give 'x' and 'y' scales."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x_sc = LinearScale()\n",
    "y_sc = LinearScale()\n",
    "\n",
    "hist = Bins(sample=x_data, scales={'x': x_sc, 'y': y_sc}, padding=0,)\n",
    "ax_x = Axis(scale=x_sc, tick_format='0.2f')\n",
    "ax_y = Axis(scale=y_sc, orientation='vertical')\n",
    "\n",
    "Figure(marks=[hist], axes=[ax_x, ax_y], padding_y=0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The midpoints of the resulting bins and their number of elements can be recovered via the read-only traits `x` and `y`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "hist.x, hist.y"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Tuning the bins\n",
    "\n",
    "Under the hood, the `Bins` mark is really a `Bars` mark, with some additional magic to control the binning. The data in `sample` is binned into equal-width bins. The parameters controlling the binning are the following traits:\n",
    "\n",
    "- `bins` sets the number of bins. It is either a fixed integer (10 by default), or the name of a method to determine the number of bins in a smart way ('auto', 'fd', 'doane', 'scott', 'rice', 'sturges' or 'sqrt').\n",
    "\n",
    "- `min` and `max` set the range of the data (`sample`) to be binned\n",
    "\n",
    "- `density`, if set to `True`, normalizes the heights of the bars.\n",
    "\n",
    "For more information, see the documentation of `numpy`'s `histogram`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x_sc = LinearScale()\n",
    "y_sc = LinearScale()\n",
    "\n",
    "hist = Bins(sample=x_data, scales={'x': x_sc, 'y': y_sc}, padding=0,)\n",
    "ax_x = Axis(scale=x_sc, tick_format='0.2f')\n",
    "ax_y = Axis(scale=y_sc, orientation='vertical')\n",
    "\n",
    "Figure(marks=[hist], axes=[ax_x, ax_y], padding_y=0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Changing the number of bins\n",
    "hist.bins = 'sqrt'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Changing the range\n",
    "hist.min = 0"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Histogram Styling\n",
    "\n",
    "The styling of `Hist` is identical to the one of `Bars`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Normalizing the count\n",
    "\n",
    "x_sc = LinearScale()\n",
    "y_sc = LinearScale()\n",
    "\n",
    "hist = Bins(sample=x_data, scales={'x': x_sc, 'y': y_sc}, density=True)\n",
    "ax_x = Axis(scale=x_sc, tick_format='0.2f')\n",
    "ax_y = Axis(scale=y_sc, orientation='vertical')\n",
    "\n",
    "Figure(marks=[hist], axes=[ax_x, ax_y], padding_y=0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# changing the color\n",
    "hist.colors=['orangered']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# stroke and opacity update\n",
    "hist.stroke = 'orange'\n",
    "hist.opacities = [0.5] * len(hist.x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Laying the histogram on its side\n",
    "hist.orientation = 'horizontal'\n",
    "ax_x.orientation = 'vertical'\n",
    "ax_y.orientation = 'horizontal'"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
